import { UnwrapRef } from 'vue'
import { merge } from 'lodash'
import { type UnData, UnConfig } from '@uni-helper/uni-network'
import http from '@/utils/http'

export type IUseRequestOptions = {
  /** 是否立即执行 */
  immediate?: boolean
  method: Method
  config?: UnConfig
}

function getDefaultOptions<T>(): IUseRequestOptions {
  return {
    immediate: false,
    method: 'post',
  }
}

/**
 * useRequest是一个定制化的请求钩子，用于处理异步请求和响应。
 * @param func 一个执行异步请求的函数，返回一个包含响应数据的Promise。
 * @param options 包含请求选项的对象 {immediate, initialData}。
 * @param options.immediate 是否立即执行请求，默认为false。
 * @returns 返回一个对象{loading, error, data, run}，包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
 */
export default function useRequest<T, P = unknown>(
  api: string | ApiPromise<P, T>,
  options?: IUseRequestOptions,
) {
  const loading = ref(false)
  const data = ref<ResponseData<T>>()
  const requestConfig = merge(getDefaultOptions<T>(), options || {})

  const request = <Params>(p?: Params) => {
    const { method, config } = requestConfig

    if (typeof api === 'string') {
      return http[method]<
        UnData, // 对应 response.data 类型
        UnData, // 对应传参中 data 类型
        T // 对应 response 类型
      >(api, merge(p, config))
    } else {
      return api
    }
  }

  const run = async <Params>(params?: Params) => {
    loading.value = true
    try {
      const response = await request(params)
      console.log('请求成功', response)

      data.value = response as ResponseData<T>
    } catch (error) {
      console.error('请求失败:', error)
    } finally {
      loading.value = false
    }
  }
  requestConfig?.immediate && run()
  return { data, loading, run }
}
